package com.LockCondition;

/**
 * lock比传统的线程模型sychronized方式更加面相对象，与生活的锁类似，
 * 两个线程执行的代码片段要实现同步互斥效果，他们必须用同一个lock对象，
 * 锁是放在代表要操作的资源类的内部方法中，而不是线程代码中。
 */

import com.TSynchronized.TestSynchronized;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 读写锁:分为读锁和写锁，多个读锁不互斥，读锁与写锁互斥，写锁与写锁互斥。
 * 这是jvm自己控制的，数据可以多人同时读，但不能同时写。
 * 如果代码修改数据，只能有一个人写，且不能同时读取，那就上写锁。
 * 总之读的时候上读的锁，写的时候上写的锁。
 * lock就是可以替换sychronized的关键字的,
 */

/**
 * ===================该例子没有读写锁，只是lock和sychronized例子的对比。
 * lock只能实现互斥，但是不能实现通信。可查看ReadWriteLockTest以及CacheDemo_lock的例子
 * Condition是实现通信的类似于传统线程技术中的Object.wait和Object.notify
 */
public class LockAndCondition {
    public static void main(String[] args) throws InterruptedException {
        new LockAndCondition().init();
    }
    private void init()
    {
       Outputer outputer=new Outputer();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true)
                {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    outputer.outpout("zhangkai");
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true)
                {
                    try {
                        Thread.sleep(20);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    outputer.outpout("liyanyan");
                }
            }
        }).start();
    }
}
class Outputer{
    Lock lock=new ReentrantLock();     //创建了锁
    public void outpout(String name) {
        int len = name.length();
        lock.lock();                    //上锁
        try {                           //害怕里面有死循环或者出现意外，不然就锁住开不开了
            synchronized (this) {
                for (int i = 0; i < len; i++) {
                    System.out.print(name.charAt(i));
                }
                System.out.println();

            }
        } finally {
            lock.unlock();             //解锁
        }
    }
    public void outpout1(String name)
    {
        int len=name.length();
        synchronized (Outputer.class) {
            for (int i = 0; i < len; i++) {
                System.out.print(name.charAt(i));
            }
            System.out.println();
        }
    }
}
